import { PlayerManager } from './Biz/PlayerManager'
import { RoomManager } from './Biz/RoomManager'
import {
  ApiMsgEnum,
  IApiGameStartReq,
  IApiGameStartRes,
  IApiPlayerJoinReq,
  IApiPlayerJoinRes,
  IApiPlayerListReq,
  IApiPlayerListRes,
  IApiRoomCreatReq,
  IApiRoomCreatRes,
  IApiRoomJoinReq,
  IApiRoomJoinRes,
  IApiRoomLeaveReq,
  IApiRoomLeaveRes,
  IApiRoomListReq,
  IApiRoomListRes,
} from './Common'
import { Connection, MyServer } from './Core'
import { getTime, symlinkCommon } from './Utils'

// 客户端<-->服务端 公用数据同步
// symlinkCommon()

// 显式声明 Connection.playerID
declare module './Core' {
  interface Connection {
    playerID: number
  }
}

const server = new MyServer({
  port: 9875,
})
/*---------------------------服务连接-----------------------*/
server.on('connection', (connection: Connection) => {
  console.log(`${getTime()}连接|连接数|${server.connections.size}`)
})
// 断开连接
server.on('disconnection', (connection: Connection) => {
  console.log(`${getTime()}断开|连接数|${server.connections.size}`)
  if (connection.playerID) {
    PlayerManager.Instance.removePlayer(connection.playerID)
  }
  PlayerManager.Instance.syncPlayers()
})
/*---------------------------api业务-----------------------*/
// 玩家加入
server.setApi(ApiMsgEnum.ApiPlayerJoin, (connection: Connection, data: IApiPlayerJoinReq): IApiPlayerJoinRes => {
  const { nickname } = data
  const player = PlayerManager.Instance.createPlayer({ nickname, connection })
  connection.playerID = player.id
  // 同步玩家列表
  PlayerManager.Instance.syncPlayers()
  return {
    player: PlayerManager.Instance.getPlayerView(player),
  }
})

// 玩家列表
server.setApi(ApiMsgEnum.ApiPlayerList, (connection: Connection, data: IApiPlayerListReq): IApiPlayerListRes => {
  return {
    list: PlayerManager.Instance.getPlayersView(),
  }
})

// 创建房间
server.setApi(ApiMsgEnum.ApiRoomCreate, (connection: Connection, data: IApiRoomCreatReq): IApiRoomCreatRes => {
  if (!connection.playerID) throw new Error('未登录')
  const room = RoomManager.Instance.createRoom()
  if (!room) throw new Error('房间不存在')
  room.join(connection.playerID)
  PlayerManager.Instance.syncPlayers()
  RoomManager.Instance.syncRooms()
  return { room: RoomManager.Instance.getRoomView(room) }
})

// 房间列表
server.setApi(ApiMsgEnum.ApiRoomList, (connection: Connection, data: IApiRoomListReq): IApiRoomListRes => {
  return {
    list: RoomManager.Instance.getRoomsView(),
  }
})

// 加入房间
server.setApi(ApiMsgEnum.ApiRoomJoin, (connection: Connection, { rid }: IApiRoomJoinReq): IApiRoomJoinRes => {
  if (!connection.playerID) throw new Error('未登录')
  const room = RoomManager.Instance.idMapRoom.get(rid)
  if (!room) throw new Error('房间不存在')
  room.join(connection.playerID)
  // 同步房内信息
  room.async()
  // 同步房间与玩家信息
  PlayerManager.Instance.syncPlayers()
  RoomManager.Instance.syncRooms()
  return { room: RoomManager.Instance.getRoomView(room) }
})

// 离开房间
server.setApi(ApiMsgEnum.ApiRoomLeave, (connection: Connection, data: IApiRoomLeaveReq): IApiRoomLeaveRes => {
  if (!connection.playerID) throw new Error('未登录')
  const player = PlayerManager.Instance.idMapPlayer.get(connection.playerID)
  if (!player) throw new Error('玩家不存在')
  const rid = player.rid
  if (!rid) throw Error('玩家不在房间')

  const room = RoomManager.Instance.idMapRoom.get(rid)
  if (!room) throw new Error('房间不存在')
  room.leave(connection.playerID)
  // 同步房内信息
  room.async()
  // 同步房间与玩家信息
  PlayerManager.Instance.syncPlayers()
  RoomManager.Instance.syncRooms()
  return { success: true }
})

// 开始游戏
server.setApi(ApiMsgEnum.ApiGameStart, (connection: Connection, data: IApiGameStartReq): IApiGameStartRes => {
  if (!connection.playerID) throw new Error('未登录')
  const player = PlayerManager.Instance.idMapPlayer.get(connection.playerID)
  if (!player) throw new Error('玩家不存在')
  const rid = player.rid
  if (!rid) throw Error('玩家不在房间')

  const room = RoomManager.Instance.idMapRoom.get(rid)
  if (!room) throw new Error('房间不存在')
  room.start()
  return { success: true }
})

server
  .start()
  .then(() => {
    console.log('启动服务')
  })
  .catch(e => {
    console.log('启动失败', e)
  })
